﻿using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using MyLib.Web.UI;

namespace MyLib.Web.Pages {
	/// <summary>
	/// 
	/// Action: 104
	/// </summary>
	public abstract class UsersPage : MyPage {
		/// <summary>
		/// 
		/// </summary>
		private const int DefaultApplicationId = 1;

		/// <summary>
		/// 
		/// </summary>
		protected int ApplicationId {
			get {
				var obj = ViewState["ApplicationId"];
				if (obj == null) {
					return DefaultApplicationId;
				} else {
					return (int)obj;
				}
			}
			set {
				ViewState["ApplicationId"] = value;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		protected void DoQuery() {
			var gridView = this.FindDescendantControl<MyGridView>("GridView1");

			gridView.PageIndex = 0;
			gridView.DataBind();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		protected bool IsDeletable() {
			var row = (System.Data.DataRowView)Page.GetDataItem();

			var userName = row.Get<string>("userName");

			return userName != "admin"; // User "admin" cannot be deleted.
		}

		/// <summary>
		/// 
		/// </summary>
		protected void DoCreateNewUser() {
			CheckAuthoriy(Context, 101);

			ViewState["EditUserId"] = "0";

			this.FindDescendantControl<System.Web.UI.Control>("FormView1").DataBind();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="userId"></param>
		protected void DoEditUser(string userId) {
			CheckAuthoriy(Context, 103);

			if (userId == null || userId.Length == 0) {
				return;
			}

			ViewState["EditUserId"] = userId;

			this.FindDescendantControl<System.Web.UI.Control>("FormView1").DataBind();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="userId"></param>
		protected void DoDeleteUser(string userId) {
			CheckAuthoriy(Context, 102);

			if (userId == null || userId.Length == 0) {
				return;
			}

			var c = GetDbProvider<MyLib.Data.AuthorityProvider>().DeleteUser(userId);
			if (c == 0) {
				var u = GetDbProvider<MyLib.Data.AuthorityProvider>().FindUserById(ApplicationId, userId);
				var rn = u.Count == 0 ? "?" : u[0].IsRealNameNull ? "?" : u[0].RealName;

				Context.AddError(string.Format(Properties.Main.ErrorUserNotDeleted, rn));
			}

			DoQuery();

			if (ViewState.Get<string>("EditUserId") == userId) {
				ViewState["EditUserId"] = null;

				this.FindDescendantControl<System.Web.UI.Control>("FormView1").DataBind();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="userId"></param>
		private void DoResetPassword(string userId) {
			CheckAuthoriy(Context, 103);

			if (userId == null || userId.Length == 0) {
				return;
			}

			GetDbProvider<MyLib.Data.AuthorityProvider>().ResetPassword(userId);

			var u = GetDbProvider<MyLib.Data.AuthorityProvider>().FindUserById(ApplicationId, userId);
			var rn = u.Count == 0 ? "?" : u[0].IsRealNameNull ? "?" : u[0].RealName;

			Context.AddInformation(string.Format(Properties.Main.SuccessResetPassword, rn));

			Context.ExecuteSafely(DoQuery);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		protected string EvalGroupName() {
			var row = (System.Data.DataRowView)Page.GetDataItem();

			var grpId = row["grpId"];

			return Context.GetCodeTextFromValue("SysCode.xml", 40, grpId);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		protected string EvalStatusText() {
			var row = (System.Data.DataRowView)Page.GetDataItem();

			var status = row.Get<int>("status");

			return status == 1 ? Properties.Main.Enabled : Properties.Main.Disabled;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="causesValidation"></param>
		/// <param name="validationGroup"></param>
		protected virtual void HandleQuery(bool causesValidation, string validationGroup) {
			this.FindDescendantControl<MyPanel>("Panel1").CopyValuesToViewState(ViewState);

			Context.ExecuteSafely(DoQuery);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="causesValidation"></param>
		/// <param name="validationGroup"></param>
		protected virtual void HandleCreateNew(bool causesValidation, string validationGroup) {
			Context.ExecuteSafely(DoCreateNewUser);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		protected override void OnInit(EventArgs e) {
			base.OnInit(e);

			// Add object datasources.
			var ds1 = new MyObjectDataSource(typeof(MyLib.Data.AuthorityProvider).AssemblyQualifiedName, "FindUsers");
			ds1.ID = "ObjectDataSource1";
			ds1.SelectCountMethod = "FindUsersCount";
			ds1.EnableCaching = false;
			ds1.EnablePaging = true;

			ds1.SelectParameters.Add("applicationId", System.Data.DbType.Int32, ApplicationId.ToString());
			ds1.SelectParameters.Add(new MyViewStateParameter {
				Name = "userName",
				Type = TypeCode.String,
				Key = "UserNameToMatch"
			});
			ds1.SelectParameters.Add(new MyViewStateParameter {
				Name = "realName",
				Type = TypeCode.String,
				Key = "RealNameToMatch"
			});
			ds1.SelectParameters.Add(new MyViewStateParameter {
				Name = "status",
				Type = TypeCode.Int32,
				Key = "StatusToMatch"
			});
			ds1.SelectParameters.Add(new MyViewStateParameter {
				Name = "groupId",
				Type = TypeCode.String,
				Key = "GroupIdToMatch"
			});
			ds1.SelectParameters.Add(new MyViewStateParameter {
				Name = "roles",
				Type = TypeCode.String,
				Key = "RoleToMatch"
			});

			var ds2 = new MyObjectDataSource(typeof(MyLib.Data.AuthorityProvider).AssemblyQualifiedName, "FindUserById");
			ds2.UpdateMethod = "SaveUser";
			ds2.ID = "ObjectDataSource2";
			ds2.EnableCaching = false;
			ds2.EnablePaging = false;

			ds2.SelectParameters.Add("applicationId", System.Data.DbType.Int32, ApplicationId.ToString());
			ds2.SelectParameters.Add(new MyViewStateParameter {
				Name = "userId",
				Type = TypeCode.String,
				Key = "EditUserId"
			});

			ds2.UpdateParameters.Add("applicationId", TypeCode.Int32, ApplicationId.ToString());
			ds2.UpdateParameters.Add("userId", TypeCode.String, "");
			ds2.UpdateParameters.Add("userName", TypeCode.String, "");
			ds2.UpdateParameters.Add("realName", TypeCode.String, "");
			ds2.UpdateParameters.Add("roles", TypeCode.String, "");
			ds2.UpdateParameters.Add("grpId", TypeCode.String, "");
			ds2.UpdateParameters.Add("status", TypeCode.Int32, "");

			var ds3 = new MyObjectDataSource(typeof(MyLib.Data.AuthorityProvider).AssemblyQualifiedName, "FindRoles");
			ds3.ID = "ObjectDataSource3";
			ds3.EnableCaching = false;
			ds3.EnablePaging = false;

			ds3.SelectParameters.Add("applicationId", System.Data.DbType.Int32, ApplicationId.ToString());
			ds3.SelectParameters.Add("roleName", TypeCode.String, "");
			ds3.SelectParameters.Add("description", TypeCode.String, "");
			ds3.SelectParameters.Add("startRowIndex", TypeCode.Int32, "");
			ds3.SelectParameters.Add("maximumRows", TypeCode.Int32, "");

			var ds4 = new MyCodeDataSource();
			ds4.ID = "CodeDataSource1";
			ds4.CategoryId = 40; // Groups.
			ds4.CodeFileName = "SysCode.xml"; // SysCode.xml

			var ds5 = new MyCodeDataSource();
			ds5.ID = "CodeDataSource2";
			ds5.Items.Add(new CodeItem { Text = Properties.Main.Enabled, Value = "1" });
			ds5.Items.Add(new CodeItem { Text = Properties.Main.Disabled, Value = "0" });
			ds5.EnableSorting = false;

			Controls.Add(ds1);
			Controls.Add(ds2);
			Controls.Add(ds3);
			Controls.Add(ds4);
			Controls.Add(ds5);

			// Assign event handlers.
			var formView1 = this.FindDescendantControl<MyFormView>("FormView1");
			formView1.DataSourceID = ds2.ID;

			var gridView1 = this.FindDescendantControl<MyGridView>("GridView1");
			gridView1.DataSourceID = ds1.ID;
			gridView1.AllowPaging = true;

			formView1.Saved += new EventHandler<MyFormViewSavedEventArgs>(OnFormView1Saved);
			formView1.Cancelled += new EventHandler<MyFormViewCommandEventArgs>(OnFormView1Cancelled);

			gridView1.RowCommand += new GridViewCommandEventHandler(OnGridView1RowCommand);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		protected override void OnLoad(EventArgs e) {
			base.OnLoad(e);

			this.Title = Properties.Main.TitleUsers;

			if (!IsPostBack) {
				this.FindDescendantControl<MyPanel>("Panel1").CopyValuesToViewState(ViewState);

				Context.ExecuteSafely(DoQuery);
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="source"></param>
		/// <param name="args"></param>
		/// <returns></returns>
		protected override bool OnBubbleEvent(object source, EventArgs args) {
			bool causesValidation = false;
			string validationGroup = string.Empty;

			if (args is CommandEventArgs) {
				IButtonControl commandSource = source as IButtonControl;
				if (commandSource != null) {
					causesValidation = commandSource.CausesValidation;
					validationGroup = commandSource.ValidationGroup;
				}

				var cargs = (CommandEventArgs)args;

				if (string.Equals(cargs.CommandName, "Query", StringComparison.OrdinalIgnoreCase)) {
					HandleQuery(causesValidation, validationGroup);
					return true;
				} else if (string.Equals(cargs.CommandName, "CreateNew", StringComparison.OrdinalIgnoreCase)) {
					HandleCreateNew(causesValidation, validationGroup);
					return true;
				} else {
					return false;
				}
			} else {
				return false;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void OnFormView1Saved(object sender, MyFormViewSavedEventArgs e) {
			ViewState["EditUserId"] = "";

			Context.ExecuteSafely(DoQuery);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void OnFormView1Cancelled(object sender, MyFormViewCommandEventArgs e) {
			ViewState["EditUserId"] = "";
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void OnGridView1RowCommand(object sender, GridViewCommandEventArgs e) {
			var arg = (string)e.CommandArgument;

			var userId = arg;

			Action act;
			switch (e.CommandName) {
				case "EditUser":
					act = () => DoEditUser(userId);
					break;
				case "DeleteUser":
					act = () => DoDeleteUser(userId);
					break;
				case "ResetPassword":
					act = () => DoResetPassword(userId);
					break;
				default:
					return;
			}

			Context.ExecuteSafely(act);
		}

	} // end of CodePage.
}
